#include "StdAfx.h"

#include "AceException.h"

#include "AceSessionImpl.h"

namespace ace
{
  namespace impl
  {
    void CAceSessionImpl::open()
    {
      ace::AceCheck(SD_Init(&m_handle), "Failed to initialize communication between the Agent and the RSA ACE/Server.", ACM_OK);

      m_env.registerSession(this);
    }

    void CAceSessionImpl::close()
    {    
      ace::AceCheck(SD_Close(m_handle), "Failed to release resources allocated with session", ACM_OK);

      m_handle = SDI_HANDLE_NONE;    

      m_env.unregisterSession(this);
    }

    bool CAceSessionImpl::lock(const std::string& username, int *ret)
    {
      assert(username.size() < 32);
      assert(isOpen());

      int code = SD_Lock(m_handle, const_cast<char *>(username.c_str()));

      if(ret) *ret = code;

      return code == ACM_OK;
    }

    bool CAceSessionImpl::check(const std::string& username, const std::string& passcode, int *ret)
    {
      assert(username.size() < 32);
      assert(passcode.size() < 20);
      assert(isOpen());

      int code = SD_Check(m_handle, const_cast<char *>(passcode.c_str()), const_cast<char *>(username.c_str()));

      if(ret) *ret = code;

      return code == ACM_OK;
    }

    bool CAceSessionImpl::next(const std::string& passcode, int *ret)
    {
      assert(passcode.size() < 20);
      assert(isOpen());

      int code = SD_Next(m_handle, const_cast<char *>(passcode.c_str()));

      if(ret) *ret = code;

      return code == ACM_OK;
    }

    bool CAceSessionImpl::setPIN(const std::string& pin, int *ret)
    {
      assert(isOpen());

      int code = SD_Pin(m_handle, const_cast<char *>(pin.c_str()));

      if(ret) *ret = code;

      if(code != ACM_NEW_PIN_ACCEPTED)
        SD_Pin(m_handle, NULL);

      return code == ACM_NEW_PIN_ACCEPTED;
    }
  } // namespace impl
} // namespace ace